package com.pi.pro.xcmg.am.was.web.cust.controller;


import com.pi.common.CodesConstants;
import com.pi.framework.core.controller.BaseCrudController;
import com.pi.framework.core.model.IEditable;
import com.pi.framework.core.service.ICrudService;
import com.pi.framework.core.util.SecurityUtils;
import com.pi.framework.core.util.StringUtils;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.pro.xcmg.am.was.fac.service.WasCustomWorkService;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.dto.act.AllocationActionDto;
import com.pi.wms.dto.doc.DocumentActionDto;
import com.pi.wms.entity.*;
import com.pi.wms.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.datatables.mapping.DataTablesInput;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Slf4j
@Controller
public abstract class BaseSoController<T, ID extends Serializable> extends BaseCrudController<T, Long> {


	@Autowired
	protected SoService proxyService;

	@Autowired
	protected SoDetailsService detailsService;

    @Autowired
	protected ParameterService parameterService;

    @Autowired
	protected WaveService waveService;

    @Autowired
	protected InventoryDetailsService inventoryService;
	
	@Autowired
	protected AllocationService allocateService;
	@Autowired
	protected TaskService taskService;

	@Autowired
	protected WasCustomWorkService wasCustomWorkService;
	
	@GetMapping(value = "check/docNumber")
	@ResponseBody
	public boolean checkCode(@RequestParam("docNumber") String docNumber, @RequestParam("oldNo") String oldNo) {
		if (!StringUtils.isBlank(oldNo) && oldNo.trim().equals(docNumber)) {
			return true;
		}
		return proxyService.countByCode(docNumber) <= 0;
	}


    @PostMapping("createwave")
    public String createWave(@RequestParam("ids") Long[] ids, Model model, HttpServletRequest request,
                             RedirectAttributes redirectAttributes) {
        model.addAttribute("params", getParams(request));

        String msg="";
        if ((ids==null) || (ids.length==0)){
            addSuccessMessage(redirectAttributes, "执行成功");
            return this.redirect("");
        }
        //
        DocumentActionDto actionDto=new DocumentActionDto();
        msg = this.wasCustomWorkService.addToWave(ids,  false, actionDto);
        if (!StringUtils.isNullOrBlank(msg)){
            addErrorMessage(redirectAttributes, "合并创建波次失败:"+msg);
        }else {
            addSuccessMessage(redirectAttributes, "执行成功");
        }
        return this.redirect("");
    }


    @PostMapping("addtowave")
    public String addToWave(@RequestParam("ids") Long[] ids, Model model, HttpServletRequest request,
                            RedirectAttributes redirectAttributes) {
        model.addAttribute("params", getParams(request));

        String msg="";
        if ((ids==null) || (ids.length==0)){
            addSuccessMessage(redirectAttributes, "执行成功");
            return this.redirect("");
        }
        //
        DocumentActionDto actionDto=new DocumentActionDto();
        msg = this.wasCustomWorkService.addToWave(ids, true, actionDto);
        if (!StringUtils.isNullOrBlank(msg)){
            addErrorMessage(redirectAttributes, "创建波次失败:"+msg);
        }else {
            addSuccessMessage(redirectAttributes, "执行成功");
        }
        return this.redirect("");
    }

	@GetMapping("del/{id}")
	public String del(@PathVariable("id") Long id, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
		model.addAttribute("params", getParams(request));
		String msg="";
		if (id != null) {
			msg=this.delete(id);
			if (!StringUtils.isNullOrBlank(msg)){
				addErrorMessage(redirectAttributes, "删除失败:"+msg);
				return super.redirect("");
			}
			addSuccessMessage(redirectAttributes, "删除数据成功");
		}
		return super.redirect("");
	}

	@PostMapping("del")
	public String del(@RequestParam("ids") Long[] ids, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
		model.addAttribute("params", getParams(request));
		String msg="";
		if (ids != null && ids.length > 0) {
			for (Long id:ids){
				msg=this.delete(id);
				if (!StringUtils.isNullOrBlank(msg)){
					addErrorMessage(redirectAttributes, "删除失败:"+msg);
					return super.redirect("");
				}
			}
			addSuccessMessage(redirectAttributes, "删除数据成功");
		}
		return super.redirect("");
	}

	@GetMapping("print/{id}")
	public String print(@PathVariable("id") Long id, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
		model.addAttribute("params", getParams(request));
		String msg="";
		if (id != null) {
			msg=this.print(id);
			if (!StringUtils.isNullOrBlank(msg)){
				addErrorMessage(redirectAttributes, "打印提交失败:"+msg);
				return super.redirect("");
			}
			addSuccessMessage(redirectAttributes, "打印提交成功");
		}
		return super.redirect("");
	}

	@PostMapping("print")
	public String print(@RequestParam("ids") Long[] ids, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
		model.addAttribute("params", getParams(request));
		String msg="";
		if (ids != null && ids.length > 0) {
			for (Long id:ids){
				msg=this.print(id);
				if (!StringUtils.isNullOrBlank(msg)){
					addErrorMessage(redirectAttributes, "打印提交失败:"+msg);
					return super.redirect("");
				}
			}
			addSuccessMessage(redirectAttributes, "打印提交成功");
		}
		return super.redirect("");
	}

	@GetMapping("close/{id}")
	public String close(@PathVariable("id") Long id, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
		model.addAttribute("params", getParams(request));
		String msg="";
		if (id != null) {
			msg=this.close(id);
			if (!StringUtils.isNullOrBlank(msg)){
				addErrorMessage(redirectAttributes, "关闭失败:"+msg);
				return super.redirect("");
			}
			addSuccessMessage(redirectAttributes, "关闭数据成功");
		}
		return super.redirect("");
	}

	@PostMapping("close")
	public String close(@RequestParam("ids") Long[] ids, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
		model.addAttribute("params", getParams(request));
		String msg="";
		if (ids != null && ids.length > 0) {
			for (Long id:ids){
				msg=this.close(id);
				if (!StringUtils.isNullOrBlank(msg)){
					addErrorMessage(redirectAttributes, "关闭失败:"+msg);
					return super.redirect("");
				}
			}
			addSuccessMessage(redirectAttributes, "关闭数据成功");
		}
		return super.redirect("");
	}

    private String print(Long id){
        String msg="";
        if (id==null){
            msg="无效的单证ID";
            return msg;
        }
        TwaDocSoHeader h = this.proxyService.findById(id);
        if (h==null){
            msg="找不到单证,请确认是否已被其他用户删除.单证ID="+String.valueOf(id);
            return msg;
        }
        if (h != null && h instanceof IEditable && !((IEditable) h).isEditable()) {
            msg="该数据为系统固定不可编辑，请选择其他操作!";
            return msg;
        }
        if (StringUtils.isNullOrBlank(h.getStatus())){
            msg="无效的单证状态,请联系系统管理员.单证号="+h.getDocumentNumber();
            return msg;
        }
        if (h.getStatus().equals(WmsConstants.ASN_STATUS_CLOSE)){
            msg="单证已经关闭.单证号="+h.getDocumentNumber();
            return msg;
        }
        if (h.getStatus().equals(WmsConstants.ASN_STATUS_CANCELL)){
            msg="单证已经取消.单证号="+h.getDocumentNumber();
            return msg;
        }
        List<TwaDocSoDetails> details=null;
        return msg;
    }


    //TODO:HU/201902.2A
	//move to service
	//but how split doc(so+details) and act(task/allocation)
	private String delete(Long id){
		String msg="";
		if (id==null){
			msg="无效的单证ID";
			return msg;
		}
		TwaDocSoHeader h = this.proxyService.findById(id);
		if (h==null){
			msg="找不到单证,请确认是否已被其他用户删除.单证ID="+String.valueOf(id);
			return msg;
		}
		if (h != null && h instanceof IEditable && !((IEditable) h).isEditable()) {
			msg="该数据为系统固定不可编辑，请选择其他操作!";
			return msg;
		}
		if (StringUtils.isNullOrBlank(h.getStatus())){
			msg="无效的单证状态,请联系系统管理员.单证号="+h.getDocumentNumber();
			return msg;
		}
		if (!h.getStatus().equals(WmsConstants.SO_STATUS_CREATE)){
			msg="非创建状态单证,不能删除.单证号="+h.getDocumentNumber();
			return msg;
		}
		if (h.getWaveId()!=null){
			msg="单据已经创建波次,不能直接删除。请先取消相关波次.";
			return msg;
		}
		List<TwaDocSoDetails> details=null;
		List<String> containers=new ArrayList<>();
		try{
			BigDecimal qty=BigDecimal.ZERO;
			details=detailsService.findByDocumentId(id);
			for (TwaDocSoDetails d:details){
				if (d==null){
					continue;
				}
				if (StringUtils.isNullOrBlank(d.getLineStatus())){
					continue;
				}
				if (!WmsConstants.ASN_STATUS_CREATE.equals(d.getLineStatus())){
					msg="存在已经作业的单证行,不能删除.单证号="+h.getDocumentNumber()+",行号="+d.getLineNumber();
					return msg;
				}
				if (d.getWaveDetailsId()!=null){
					msg="单据行已经创建波次,不能直接删除。请先取消相关波次.行号="+d.getLineNumber()+",物料"+d.getMaterialCode();
					return msg;
				}
				qty=d.getQtyAllocatedEach();
				if ((qty!=null) && (qty.compareTo(BigDecimal.ZERO)>0)){
					msg="存在已经分配的单证行,请先取消分配.单证号="+h.getDocumentNumber()+",行号="+d.getLineNumber();
					return msg;
				}
				qty=d.getQtyShippedEach();
				if ((qty!=null) && (qty.compareTo(BigDecimal.ZERO)>0)){
					msg="存在已经发货的单证行,不能删除.单证号="+h.getDocumentNumber()+",行号="+d.getLineNumber();
					return msg;
				}
				if (!StringUtils.isNullOrBlank(d.getCheckContainNumber())){
                    if (!containers.contains(d.getCheckContainNumber())){
                        containers.add(d.getCheckContainNumber());
                    }
                }
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		List<TwtActAllocationList> allocations=null;
		try{
			allocations=allocateService.findByDocId(id);
			if ((allocations!=null) && (allocations.size()>0)){
				msg="已经分配,不能删除.单证号="+h.getDocumentNumber();
				return msg;
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		List<TwtActTaskList> tasks=null;
		try{
			tasks=taskService.queryWorkingTasks(WmsConstants.TASK_TYPE_PICK, h.getId());
			if ((tasks!=null) && (tasks.size()>0)){
				msg="已经生成任务,不能删除.单证号="+h.getDocumentNumber();
				return msg;
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		try{
			if ((tasks!=null) && (tasks.size()>0)){
				this.taskService.delete(tasks);
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		try{
			if ((allocations!=null) && (allocations.size()>0)){
				this.allocateService.delete(allocations);
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}

		//
        List<TwaInventoryDetails> storages=null;
        try{
            if ((containers!=null) && (containers.size()>0)){
                for (String cn:containers){
                    if (StringUtils.isNullOrBlank(cn)){
                        continue;
                    }
                    storages=this.inventoryService.findByContainNumber(cn);
                    if ((storages==null)||(storages.size()==0)){
                        continue;
                    }
                    for (TwaInventoryDetails nd:storages){
                        if (!XcmgAmConstants.MATERIAL_ID_KIT.equals(nd.getMaterialId())){
                            continue;
                        }
                        if (StringUtils.isNullOrBlank(nd.getReserveDocNumber())){
                            continue;
                        }
                        nd.setReserveDocNumber(null);
                        this.inventoryService.save(nd);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        //
		try{
			if ((details!=null) && (details.size()>0)){
				this.detailsService.delete(details);
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		try{
			this.proxyService.delete(h);
		}catch(Exception e){
			msg=e.getMessage();
		}
		return msg;
	}

	private String close(Long id){
		String msg="";
		if (id==null){
			msg="无效的单证ID";
			return msg;
		}
		TwaDocSoHeader h = this.proxyService.findById(id);
		if (h==null){
			msg="找不到单证,请确认是否已被其他用户删除.单证ID="+String.valueOf(id);
			return msg;
		}
		if (h != null && h instanceof IEditable && !((IEditable) h).isEditable()) {
			msg="该数据为系统固定不可编辑，请选择其他操作!";
			return msg;
		}
		if (StringUtils.isNullOrBlank(h.getStatus())){
			msg="无效的单证状态,请联系系统管理员.单证号="+h.getDocumentNumber();
			return msg;
		}
		if (h.getStatus().equals(WmsConstants.ASN_STATUS_CLOSE)){
			msg="单证已经关闭.单证号="+h.getDocumentNumber();
			return msg;
		}
		if (h.getStatus().equals(WmsConstants.ASN_STATUS_CANCELL)){
			msg="单证已经取消.单证号="+h.getDocumentNumber();
			return msg;
		}
		List<TwaDocSoDetails> details=null;
		try{
			details=detailsService.findByDocumentId(id);
			for (TwaDocSoDetails d:details){
				if (d==null){
					continue;
				}
				if (StringUtils.isNullOrBlank(d.getLineStatus())){
					continue;
				}
				/**
				if (!WmsConstants.ASN_STATUS_CREATE.equals(d.getLineStatus())){
					msg="存在已经作业的单证行,不能删除.单证号="+m.getDocumentNumber()+",行号="+d.getLineNumber();
					return msg;
				}
				qty=d.getQtyPalletizedEach();
				if ((qty!=null) && (qty.compareTo(BigDecimal.ZERO)>0)){
					msg="存在已经码盘的单证行,请先清除码盘数据.单证号="+m.getDocumentNumber()+",行号="+d.getLineNumber();
					return msg;
				}
				qty=d.getQtyReceivedEach();
				if ((qty!=null) && (qty.compareTo(BigDecimal.ZERO)>0)){
					msg="存在已经收货的单证行,不能删除.单证号="+m.getDocumentNumber()+",行号="+d.getLineNumber();
					return msg;
				}
				**/
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		List<TwtActAllocationList> allocations=null;
		try{
			allocations=allocateService.findByDocId(id);
			for (TwtActAllocationList a:allocations){
				if (a==null){
					continue;
				}
				if (StringUtils.isNullOrBlank(a.getStatus())){
					continue;
				}
				if ((!WmsConstants.SO_STATUS_CLOSE.equals(a.getStatus()))
						&& (!WmsConstants.SO_STATUS_SHIP.equals(a.getStatus()))){
					msg="存在尚未完成的拣货,不能关闭.单证号="+h.getDocumentNumber();
					return msg;
				}
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		List<TwtActTaskList> tasks=taskService.queryWorkingTasks(WmsConstants.TASK_TYPE_PICK, id);
		if ((tasks!=null) && (tasks.size()>0)){
			for (TwtActTaskList t:tasks){
				if (t==null){
					continue;
				}
				if (StringUtils.isNullOrBlank(t.getStatus())){
					continue;
				}
				if ((!WmsConstants.TASK_STATUS_CLOSE.equals(t.getStatus()))
						&& (!WmsConstants.TASK_STATUS_CANCEL.equals(t.getStatus()))){
					msg="尚未拣货任务未完成,不能关闭.单证号="+h.getDocumentNumber();
					return msg;
				}
			}
		}
		try{
			if ((details!=null) && (details.size()>0)){

				for (TwaDocSoDetails d:details){
					if (d==null){
						continue;
					}
					if (WmsConstants.SO_STATUS_CLOSE.equals(d.getLineStatus())){
						continue;
					}
					if (WmsConstants.SO_STATUS_CANCELL.equals(d.getLineStatus())){
						continue;
					}
					d.setLineStatus(WmsConstants.ASN_STATUS_CLOSE);
					d.setLastModifiedDate(new Date());
					d.setLastModifiedBy(SecurityUtils.getLoginUsername());
				}
				this.detailsService.update(details);
			}
		}catch(Exception e){
			msg=e.getMessage();
			return msg;
		}
		try{
			h.setStatus(WmsConstants.SO_STATUS_CLOSE);
			h.setLastModifiedDate(new Date());
			h.setLastModifiedBy(SecurityUtils.getLoginUsername());
			this.proxyService.update(h);
		}catch(Exception e){
			msg=e.getMessage();
		}
		return msg;
	}

	private List<TwtActAllocationList> allocate(String batchNumber, TwaDocSoHeader header, AllocationActionDto actionDto){
		List<TwtActAllocationList> allocations=null;
		if (header==null){
			return allocations;
		}
		this.fill(header, actionDto);
		try {
			allocations = this.allocateService.allocate(batchNumber, header.getDocumentNumber(), "", actionDto);
		}catch (Exception e){
			e.printStackTrace();
			log.error("ApiService BaseSoApiService create.allocate error//{doc:{},error:{}}",header.getDocumentNumber(),e.getMessage());
		}
		return allocations;
	}

	private void fill(TwaDocSoHeader document, AllocationActionDto actionDto){
		if ((document==null)||(actionDto==null)){
			return;
		}
		actionDto.setReleaseStatus(CodesConstants.COMMON_RELEASE_STATUS_CREATED);
		actionDto.setPackAllocateMode(CodesConstants.COMMON_FLAG_NO);
		/**
		 if (!com.pi.common.utils.StringUtils.isNullOrBlank(document.getPackallocationmode())){
		 actionDto.setPackAllocateMode(document.getPackallocationmode().trim());
		 }
		 **/
		actionDto.setWorker(SecurityUtils.getLoginUsername());
	}
}
